<route lang="json">
{
    "name": "menuManage",
    "meta": {
        "title": "控制台-菜单管理",
        "requiresAuth": true
    }
}
</route>

<script setup lang="ts">
import { ElMessage, ElMessageBox } from 'element-plus'
import { computed, onMounted, reactive, ref } from 'vue'
import { addMenu, deleteMenu, getMenuList, updateMenu } from '~/api/menu'

// 菜单列表数据
const menuList = ref<MenuItem[]>([])
const loading = ref(false)

// 对话框控制
const dialogVisible = ref(false)
const dialogTitle = ref('添加菜单')
const formLoading = ref(false)

interface MenuItem {
  _id: string
  status: number
  children: object[]
  menuUrl?: string
  menuName: string
  menuIcon: string
  __v: number
}

// 表单数据
const formData = reactive<MenuItem>({
  _id: '',
  status: 1,
  children: [],
  menuUrl: '',
  menuName: '',
  menuIcon: '',
  __v: 0,
})

// 表单规则
const rules = {
  menuName: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
  menuIcon: [{ required: true, message: '请输入菜单图标名称', trigger: 'blur' }],
}

const formRef = ref()

// 获取菜单列表
async function fetchMenuList() {
  loading.value = true
  try {
    const res = await getMenuList()
    if (res) {
      menuList.value = res.menuTree
    }
  }
  catch (error) {
    console.error('获取菜单列表失败:', error)
    ElMessage.error('获取菜单列表失败')
    menuList.value = []
  }
  finally {
    loading.value = false
  }
}

// 打开添加对话框
function openAddDialog(parentId = '') {
  dialogTitle.value = parentId ? '添加子菜单' : '添加菜单'
  Object.assign(formData, {
    status: 1,
    menuUrl: '',
    menuName: '',
    menuIcon: '',
    __v: 0,
  })
  dialogVisible.value = true
}

// 打开编辑对话框
function openEditDialog(row: MenuItem) {
  dialogTitle.value = '编辑菜单'
  Object.assign(formData, {
    _id: row._id,
    status: row.status,
    children: row.children,
    menuUrl: row.menuUrl || '/',
    menuName: row.menuName,
    menuIcon: row.menuIcon,
    __v: row.__v,
  })
  dialogVisible.value = true
}

// 提交表单
async function submitForm() {
  if (!formRef.value)
    return

  await formRef.value.validate(async (valid: boolean) => {
    if (!valid)
      return

    formLoading.value = true
    try {
      const menuData = {
        menuUrl: formData.menuUrl || '/',
        menuName: formData.menuName,
        menuIcon: formData.menuIcon,
        status: formData.status,
      }

      if (formData._id) {
        // 编辑
        await updateMenu(formData._id, menuData)
        ElMessage.success('更新菜单成功')
      }
      else {
        // 添加
        await addMenu(menuData)
        ElMessage.success('添加菜单成功')
      }
      dialogVisible.value = false
      fetchMenuList()
    }
    catch (error) {
      console.error('操作失败:', error)
      ElMessage.error('操作失败')
    }
    finally {
      formLoading.value = false
    }
  })
}

// 删除菜单
function handleDelete(row: any) {
  ElMessageBox.confirm('确定要删除该菜单吗？子菜单也将被删除！', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(async () => {
    try {
      await deleteMenu(row._id)
      ElMessage.success('删除成功')
      fetchMenuList()
    }
    catch (error) {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
    }
  }).catch(() => {})
}

// 获取父级菜单选项
const parentMenuOptions = computed(() => {
  return [
    { label: '无 (作为一级菜单)', value: '' },
    ...menuList.value
      .filter(item => !item._id) // 只显示一级菜单作为父级选项
      .map(item => ({
        label: item.menuName,
        value: item._id,
      })),
  ]
})

// 图标选项
const iconOptions = [
  { label: '数据看板', value: 'DataBoard' },
  { label: '位置', value: 'Location' },
  { label: '用户', value: 'UserFilled' },
  { label: '图片', value: 'Picture' },
  { label: '购物车', value: 'ShoppingCart' },
  { label: '操作', value: 'Operation' },
  { label: '通知', value: 'BellFilled' },
  { label: '购物车满', value: 'ShoppingCartFull' },
  { label: '商品', value: 'Goods' },
  { label: '用户', value: 'User' },
  { label: '办公楼', value: 'OfficeBuilding' },
]

// 页面加载时获取菜单列表
onMounted(() => {
  fetchMenuList()
})
</script>

<template>
  <div class="menu-manage-container">
    <div class="menu-header">
      <h2 class="menu-title">
        菜单管理
      </h2>
      <el-button type="primary" @click="openAddDialog()">
        添加菜单
      </el-button>
    </div>

    <!-- 菜单列表 -->
    <el-card shadow="hover" class="menu-card">
      <el-table
        v-loading="loading" :data="menuList" row-key="id" default-expand-all border
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      >
        <el-table-column type="index" label="序号" width="60" />

        <!-- 菜单名称列 -->
        <el-table-column prop="menuName" label="菜单名称" min-width="160" />

        <!-- 图标列 -->
        <el-table-column label="图标" width="120">
          <template #default="scope">
            <el-tag v-if="scope.row.menuIcon" type="info">
              {{ scope.row.menuIcon }}
            </el-tag>
            <span v-else>-</span>
          </template>
        </el-table-column>

        <!-- 路径列 -->
        <el-table-column prop="menuUrl" label="路径" min-width="180" show-overflow-tooltip />

        <!-- 状态列 -->
        <el-table-column prop="status" label="状态" min-width="100">
          <template #default="scope">
            <el-tag :type="scope.row.status === 1 ? 'success' : 'warning'" disable-transitions>
              {{ scope.row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>

        <!-- 操作列 -->
        <el-table-column label="操作" width="250" fixed="right">
          <template #default="scope">
            <el-button type="primary" link @click="openAddDialog(scope.row._id)">
              添加子菜单
            </el-button>
            <el-button type="primary" link @click="openEditDialog(scope.row)">
              编辑
            </el-button>
            <el-button type="danger" link @click="handleDelete(scope.row)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 添加/编辑对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px" destroy-on-close>
      <el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
        <el-form-item label="上级菜单">
          <el-select v-model="formData._id" placeholder="请选择上级菜单" style="width: 100%">
            <el-option v-for="item in parentMenuOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>

        <el-form-item label="菜单名称" prop="title">
          <el-input v-model="formData.menuName" placeholder="请输入菜单名称" />
        </el-form-item>

        <el-form-item label="菜单路径" prop="path">
          <el-input v-model="formData.menuUrl" placeholder="请输入菜单路径" />
        </el-form-item>

        <el-form-item label="菜单图标">
          <el-select v-model="formData.menuIcon" placeholder="请选择菜单图标" style="width: 100%">
            <el-option v-for="item in iconOptions" :key="item.value" :label="item.label" :value="item.value">
              <div style="display: flex; align-items: center;">
                <el-icon>
                  <component :is="item.value" />
                </el-icon>
                <span style="margin-left: 8px">{{ item.label }}</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="状态">
          <el-switch
            v-model="formData.status" inline-prompt
            :active-value="1"
            :inactive-value="0"
            active-text="启用"
            inactive-text="禁用"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="formLoading" @click="submitForm">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.menu-manage-container {
  padding: 20px;

  .menu-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;

    .menu-title {
      font-size: 20px;
      font-weight: 600;
      margin: 0;
    }
  }

  .menu-card {
    margin-bottom: 20px;
  }
}
</style>
